﻿using Microsoft.EntityFrameworkCore;
using Sgr.DataCategories.Domain.DataCategoryItem;
using Sgr.Domain.Entities;
using Sgr.EntityFrameworkCore;

namespace Sgr.DataCategories.Services
{
    /// <summary>
    /// 数据字典提供者的默认实现
    /// </summary>
    public class DataDictionaryProvider : IDataDictionaryProvider
    {
        private readonly IServiceScopeFactory _scopeFactory;

        /// <summary>
        /// 初始化数据字典提供者
        /// </summary>
        /// <param name="scopeFactory"></param>
        /// <exception cref="ArgumentNullException">当参数为null时抛出</exception>
        public DataDictionaryProvider(IServiceScopeFactory scopeFactory)
        {
            _scopeFactory = scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory));
        }

        /// <summary>
        /// 异步获取指定类别的数据字典项
        /// </summary>
        /// <param name="category">数据字典类别</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>数据字典项列表</returns>
        /// <exception cref="ArgumentNullException">当category为null或空时抛出</exception>
        public async Task<IList<NameValue>> GetItemsAsync(string category, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(category))
                throw new ArgumentNullException(nameof(category));

            if (!IsCategorySupported(category))
                return new List<NameValue>();

            using var scope = _scopeFactory.CreateScope();
            await using var context = scope.ServiceProvider.GetRequiredService<SgrReadOnlyDbContext>();
            var items = await context
                    .Set<DataCategoryItem>()
                    .AsNoTracking()
                    .Where(f => f.CategoryTypeCode == category && f.State == EntityStates.Normal)
                    .OrderBy(x => x.OrderNumber)
                    .ToListAsync(cancellationToken);

            return items.Select(x => new NameValue(x.DcItemName, x.DcItemValue)).ToList();
        }

        /// <summary>
        /// 判断是否支持指定类别的数据字典
        /// </summary>
        /// <param name="category">数据字典类别</param>
        /// <returns>如果支持返回true，否则返回false</returns>
        public bool IsCategorySupported(string category)
        {
            if (string.IsNullOrEmpty(category))
                return false;

            var types = CategoryTypeProvider.CategoryTypes;
            if (types == null)
                return false;

            return types.Any(x => x.Value == category);
        }
    }
}